package com.javawork.juc.five;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * 以一种线程安全的方式操作非线程安全对象的某些字段。
 * 需求：
 * 10个线程，每个线程转账1000，不使用synchronized，尝试使用AtomicIntegerFieldupdater来实现。
 * @author zhangxiaolu
 * @since 2023-02-12 16:47
 */
public class AtomicIntegerFieldUpdaterDemo {

    public static void main(String[] args) throws InterruptedException {
        BankAccount bankAccount = new BankAccount();
        CountDownLatch countDownLatch = new CountDownLatch(10);
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    for (int j = 0; j < 1000; j++) {
//                        bankAccount.add();
                        bankAccount.transMoney(bankAccount);
                    }
                } finally {
                    countDownLatch.countDown();
                }
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() + "\t result : " + bankAccount.money);
    }
}

class BankAccount {
    String bankName = "CCB";

    public volatile int money = 0;

    public synchronized void add() {
        money++;
    }

    /**
     * 因为对象的属性修改类型原子类都是抽象类，所以每次使用都必须使用静态方法newUpdater（）创建一个更新器，并且需要设置想要更新的类和属性。
     */
    AtomicIntegerFieldUpdater<BankAccount> fieldUpdater = AtomicIntegerFieldUpdater.newUpdater(BankAccount.class, "money");
    //不加synchronized，保证高性能原子性，相当于局部微创的小手术
    public void transMoney(BankAccount bonkAccount) {
        fieldUpdater.getAndIncrement(bonkAccount);
    }

}